package top.lc951.myglide.load.engine.bitmap_recycle;

import android.annotation.TargetApi;
import android.graphics.Bitmap;
import android.os.Build;

import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;

import top.lc951.myglide.BitmapPool;
import top.lc951.myglide.util.Synthetic;

/** TODO: 2/10/22
 * 1)池技术
 * 2）Lru算法
 * 3）应用场景
 *
 * */
public class LruBitmapPool implements BitmapPool {
    private static final String TAG = "LruBitmapPool";
    private static final Bitmap.Config DEFAULT_CONFIG = Bitmap.Config.ARGB_8888;
    private final LruPoolStrategy strategy;
    private final Set<Bitmap.Config> allowedConfigs;
    private final long initialMaxSize;
    private final BitmapTracker tracker;

    private long maxSize;
    private long currentSize;
    private int hits;
    private int misses;
    private int puts;
    private int evictions;

    // Exposed for testing only.
    LruBitmapPool(long maxSize, LruPoolStrategy strategy, Set<Bitmap.Config> allowedConfigs) {
        this.initialMaxSize = maxSize;
        this.maxSize = maxSize;
        this.strategy = strategy;
        this.allowedConfigs = allowedConfigs;
        this.tracker = new NullBitmapTracker();
    }

    /**
     * Constructor for LruBitmapPool.
     *
     * @param maxSize The initial maximum size of the pool in bytes.
     */
    public LruBitmapPool(long maxSize) {
        this(maxSize, getDefaultStrategy(), getDefaultAllowedConfigs());
    }

    private static LruPoolStrategy getDefaultStrategy() {
        final LruPoolStrategy strategy;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            strategy = new SizeConfigStrategy();
        } else {
            strategy = new AttributeStrategy();
        }
        return strategy;
    }
    @TargetApi(Build.VERSION_CODES.O)
    private static Set<Bitmap.Config> getDefaultAllowedConfigs() {
        Set<Bitmap.Config> configs = new HashSet<>(Arrays.asList(Bitmap.Config.values()));
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            // GIFs, among other types, end up with a native Bitmap config that doesn't map to a java
            // config and is treated as null in java code. On KitKat+ these Bitmaps can be reconfigured
            // and are suitable for re-use.
            configs.add(null);
        }
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            configs.remove(Bitmap.Config.HARDWARE);
        }
        return Collections.unmodifiableSet(configs);
    }
    private interface BitmapTracker {
        void add(Bitmap bitmap);

        void remove(Bitmap bitmap);
    }

    private static final class NullBitmapTracker implements BitmapTracker {

        @Synthetic
        NullBitmapTracker() {}

        @Override
        public void add(Bitmap bitmap) {
            // Do nothing.
        }

        @Override
        public void remove(Bitmap bitmap) {
            // Do nothing.
        }
    }
}
